//
//  LYUIMacros.h
//  LYDevelopKit
//
//  Created by 李阳 on 2018/5/31.
//


/// 开发中常用宏定义

#ifndef LYUIMacros_h
#define LYUIMacros_h

// =======================================
// 控制台打印
// =======================================

#ifdef DEBUG
#define LYLog(...) NSLog(__VA_ARGS__)
#define LYShow(FORMAT, ...) \
{\
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];\
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];\
[fmt setTimeZone:timeZone];\
[fmt setDateFormat:@"HH:mm:ss.SSSZ"];\
NSString *time = [fmt stringFromDate:[NSDate date]];\
fprintf(stderr,"%s\t[%s:%d]\t%s\n", [time UTF8String], [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);\
}
#define LYPrint(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])
#else
#define LYLog(...)
#define LYShow(FORMAT, ...)
#define LYPrint(FORMAT, ...)
#endif

#define LYLogFunc LYLog(@"%s", __func__)
#define LYShowFunc LYShow(@"%s", __PRETTY_FUNCTION__)


// =======================================
// 常用尺寸
// =======================================

#define kScreenW ([[UIScreen mainScreen] bounds].size.width)
#define kScreenH ([[UIScreen mainScreen] bounds].size.height)

#define kScale_6 (KScreenWidth/375.0)

#define kScaleValue(value) ((value)*kScale_6)

// =======================================
// 单例访问
// =======================================

#define kScreen [UIScreen mainScreen]
#define kDevice [UIDevice currentDevice]
#define kApplication [UIApplication sharedApplication]
#define kAppDelegate [UIApplication sharedApplication].delegate
#define kFileManager [NSFileManager defaultManager]
#define kUserDefaults [NSUserDefaults standardUserDefaults]
#define kNotificationCenter [NSNotificationCenter defaultCenter]
#define kKeyWindow [UIApplication sharedApplication].keyWindow


// =======================================
// 机型判断
// =======================================

#ifndef kIphone4
#define kIphone4  CGSizeEqualToSize(CGSizeMake(320, 480), [UIScreen mainScreen].bounds.size)
#endif

#ifndef kIphone5
#define kIphone5  CGSizeEqualToSize(CGSizeMake(320, 568), [UIScreen mainScreen].bounds.size)
#endif

#ifndef kIphone6
#define kIphone6  CGSizeEqualToSize(CGSizeMake(375, 667), [UIScreen mainScreen].bounds.size)
#endif

#ifndef kIphone6P
#define kIphone6P CGSizeEqualToSize(CGSizeMake(414, 736), [UIScreen mainScreen].bounds.size)
#endif

#ifndef kIphoneX
#define kIphoneX  CGSizeEqualToSize(CGSizeMake(375, 812), [UIScreen mainScreen].bounds.size)
#endif

#ifndef kIpad
#define kIpad [[UIDevice currentDevice].model isEqualToString:@"iPad"]
#endif


// =======================================
// 强弱引用
// =======================================

#ifndef weakify
    #if DEBUG
        #if __has_feature(objc_arc)
            #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
        #else
            #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
        #endif
    #else
        #if __has_feature(objc_arc)
            #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
        #else
            #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
        #endif
    #endif
#endif

#ifndef strongify
    #if DEBUG
        #if __has_feature(objc_arc)
            #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
        #else
            #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
        #endif
    #else
        #if __has_feature(objc_arc)
            #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
        #else
            #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
        #endif
    #endif
#endif

// =======================================
// 扩展增加包体积的解决办法
// =======================================

/**
 Add this macro before each category implementation, so we don't have to use
 -all_load or -force_load to load object files from static libraries that only
 contain categories and no classes.
 More info: http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html .
 *******************************************************************************
 Example:
 LYSYNTH_DUMMY_CLASS(NSString_YYAdd)
 */
#ifndef LYSYNTH_DUMMY_CLASS
#define LYSYNTH_DUMMY_CLASS(_name_) \
@interface LYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
@implementation LYSYNTH_DUMMY_CLASS_ ## _name_ @end
#endif


// =======================================
// 单例
// =======================================

#ifndef Singleton
#define Singleton

#ifdef __OBJC__

/// .h文件内容
#define SingleInterface(name) + (instancetype)shared##name;

/// .m文件内容
#if __has_feature(objc_arc)
#define SingleImplementation(name) \
+ (instancetype)shared##name { return [[self alloc]init]; } \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static id instance; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
instance = [super allocWithZone:zone]; \
}); \
return instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ return self; } \
- (id)mutableCopyWithZone:(NSZone *)zone { return self; }

#else

#define SingleImplementation(name) \
+ (instancetype)shared##name { return [[self alloc]init]; } \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static id instance; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
instance = [super allocWithZone:zone]; \
}); \
return instance; \
} \
- (id)copyWithZone:(NSZone *)zone { return self; } \
- (id)mutableCopyWithZone:(NSZone *)zone { return self; } \
- (instancetype)retain { return self; } \
- (instancetype)autorelease { return self; } \
- (oneway void)release {} \
- (NSUInteger)retainCount { return MAXFLOAT; } \

#endif

#endif

#endif /* Singleton */


#endif /* LYUIMacros_h */
